package com.xxx.controller;

import com.xxx.entity.User;
import com.xxx.service.UserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class LoginController {

    @Autowired
    private UserService userService;

    @RequestMapping("/toLogin")
    public String toLogin(){
        System.out.println("toLogin");
        return "/login";
    }

    /*
     * 方法：查询ID
     * 作用：次方法存在只是测试，方法返回的数据类型的void，可以正常运行，但是Shiro框架配置的原因会造成方法走完后控制层爆出错误提示。(待：了解名称补充)
     * */
    @RequestMapping("/selectId")
    public void selectId(int id){
        System.out.println("selectId");
        System.out.println("ID:" + id);

        User user = new User();
        user = userService.selectId(id);
        System.out.println("ID:" + user.getId());
        System.out.println("userName:" + user.getUsername());
        System.out.println("passWord:" + user.getPassword());
    }

    /**
     * 方法：登录
     *
     * 参数：
     *      Model model：用处是给前端返回信息
     * */
    @RequestMapping("/login")
    public String login(String username,String password,Model model){
        System.out.println("login:");
        System.out.println("username:" + username);
        System.out.println("password:" + password);

        // 使用Shiro编写认证操作
        // 1.获取Security
        Subject subject = SecurityUtils.getSubject();

        // 2.封装用户数据
        UsernamePasswordToken token = new UsernamePasswordToken(username,password);

        // 3.执行登录方法
        /**
         * 如果判断登录是否成功呢？
         * 答：通过try方式判断，如果没有任何异常则表示登录成功
         * 备注：
         *   Shiro也提供了比较细致的失败情况：帐号不存在、密码错误。
         *      答：使用：UnknownAccountException，如果符合则表示帐号不存在
         *
         *   subject.login(token);是怎么执行的呢？
         *      答：会调用UserRealm中的AuthenticationInfo方法
         *
         * return "login";           写法表示跳转的是页面
         * return "redirect:/login"; 写法表示《重定向》，但是重定向后addAttribute的消息无法传到前端
         * */
        try {
            // 登录（验证）
            System.out.println("登录验证！");

            subject.login(token);
            return "thymeleaf";
        } catch (UnknownAccountException e) {
            // 登录失败：帐号不存在
            System.out.println("登录失败：帐号不存在！");

            // 给前端返回信息
            model.addAttribute("msg","帐号不存在！");
            return "login";
        } catch (IncorrectCredentialsException e){
            // 登录失败：密码错误
            System.out.println("登录密码错误！");

            // 给前端返回信息
            model.addAttribute("msg","密码错误！");
            return "login";
        }
    }

    // 跳转《未授权》页面
    @RequestMapping("/toNoAuthc")
    public String noAuthc(){
        System.out.println("toNoAuthc");
        return "noAuthc";
    }
}
